package com.zmn.oms.api.controller.third.jingdong;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jdwl.open.api.sdk.response.lasim.LasImHfsOrderSearchResponse;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.http.HttpUtil;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.order.proxy.CreateOrderDTO;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.ZsOrderWorkVO;
import com.zmn.oms.third.jingdong.JingdongConsts;
import com.zmn.oms.third.jingdong.JingdongTokenManager;
import com.zmn.oms.third.jingdong.dto.JingdongAccessToken;
import com.zmn.oms.third.jingdong.service.JingdongService;
import com.zmn.oms.zmn.business.interfaces.proxy.ProxyOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkQueryBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 类描述：
 *
 * @author LiangHailong
 * @date 2019/09/03 15:23
 */
@RestController
@RequestMapping("/jingdongservice")
@Slf4j
public class JingdongServicePlusController {

    @Autowired
    private ProxyOrderBService proxyOrderBService;
    @Autowired
    protected ZsOrderWorkQueryBService zsOrderWorkQueryBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Autowired
    private JingdongService jingdongService;


    @GetMapping("/oauth")
    public void oauth(HttpServletResponse resp) {
        try {
            String callbackUrl = JingdongConsts.REDIRECT_URL + "/jingdongservice/callback/token";
            String url = String.format("%s?response_type=code&view=web&state=1212&client_id=%s&redirect_uri=%s",
                    JingdongConsts.AUTHORIZE_CODE_URL, JingdongConsts.APPKEY,
                    URLEncoder.encode(callbackUrl, GlobalConsts.UTF8_ENCODING));
            resp.sendRedirect(url);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    @GetMapping("/callback/token")
    public void getAccessTokenByCode(String code, HttpServletResponse resp) {
        String url = JingdongConsts.TOKEN_URL;
        Map<String, String> props = new HashMap();
        props.put("grant_type", "authorization_code");
        props.put("client_id", JingdongConsts.APPKEY);
        props.put("client_secret", JingdongConsts.SECRET);
        props.put("redirect_uri", JingdongConsts.REDIRECT_URL);

        props.put("code", code);

        String result = null;
        try {
            JingdongAccessToken token = new JingdongAccessToken();

            // 保存token
            result = HttpUtil.post(url, props);
            String json = org.apache.commons.lang.StringEscapeUtils.unescapeJava(result);
            if (json.startsWith("\"") && json.endsWith("\"")) {
                json = json.substring(1, json.length() -1);
            }
            JSONObject jsonObject = JSON.parseObject(json);

            token.setAccessToken(jsonObject.getString("accessToken"));
            token.setAccessExpire(jsonObject.getString("accessExpire"));
            token.setRefreshToken(jsonObject.getString("refreshToken"));
            token.setRefreshExpire(jsonObject.getString("refreshExpire"));
            token.setCode(jsonObject.getString("code"));
/*
            token.setAccessToken("");
            token.setAccessExpire("");
            token.setRefreshToken("");
            token.setRefreshExpire("");
            token.setCode("");
*/
            JingdongTokenManager.setToken(token);

            ServletOutputStream out = resp.getOutputStream();
            out.print(String.format("code:[%s], result:[%s]", code, result));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }


    @PostMapping("/order/add")
    @ResponseBody
    public ResultDTO testOrder(HttpServletRequest request) {
        String sign = request.getParameter("sign");
        String param = request.getParameter("param");
        if (!"jingdongservicetest".equals(sign) || StringUtils.isBlank(param)) {
            return ResultDTO.fail("参数有误");
        }

        LasImHfsOrderSearchResponse response = null;
        try {
            response = JSON.parseObject(param, LasImHfsOrderSearchResponse.class);
            List<OrderBO> orderBOS = jingdongService.saveOrder4Remedy(response);

            List<OrderWork> collect = orderBOS.stream().map(OrderBO::getOrderWork).collect(Collectors.toList());

            return ResultDTO.success(collect);
        } catch (Exception e) {
            return ResultDTO.fail("参数格式有误");
        }
    }

    @PostMapping("/order/addByQueryCode")
    @ResponseBody
    public ResultDTO addByQueryCode(HttpServletRequest request) {
        String sign = request.getParameter("sign");
        String queryCode = request.getParameter("queryCode");

        log.info("#JingdongServicePlus#addByQueryCode#- sign=[{}], queryCode=[{}]", sign, queryCode);

        if (!"jingdongservicetest".equals(sign) || StringUtils.isBlank(queryCode)) {
            return ResultDTO.fail("参数有误");
        }

        jingdongService.pullOrderByQueryCode(queryCode);

        return ResultDTO.success();
    }

    /**
     * 幂等校验去重
     * @param orderDTOList
     * @return
     */
    private List<CreateOrderDTO> filterDuplicate(List<CreateOrderDTO> orderDTOList) {
        List<CreateOrderDTO> addList = new LinkedList<>();
        for (CreateOrderDTO item : orderDTOList) {
            ZsOrderWorkVO orderWork =
                    zsOrderWorkQueryBService.findOrderWorkByOuterId(item.getOuterId(), JingdongConsts.CHANNEL_ID);
            if (orderWork == null) {
                addList.add(item);
            }
        }

        return addList;
    }

    /**
     * 保存订单
     * @param createOrderDTO
     */
    private void saveOrder(CreateOrderDTO createOrderDTO) {
        try {
            OrderBO orderBO = proxyOrderBService.createOrder(createOrderDTO);
            OrderWork orderWork = orderBO.getOrderWork();
            log.info("【{}】保存订单成功。OrderWork:[{}]", JingdongConsts.CHANNEL_NAME,
                    JSON.toJSON(orderBO.getOrderWork()));

            // 工单自动流转
            workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());
        } catch (Exception e) {
            log.info("【{}】保存订单失败。CreateOrderDTO:[{}]",
                    JingdongConsts.CHANNEL_NAME, JSON.toJSON(createOrderDTO));
            log.error(e.getMessage(), e);
        }
    }

}
